﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace Lyon.Utility
{
    /// <summary>
    /// 排序器。
    /// </summary>
    public class Sorter<T> : IComparer<T>
    {
        static BindingFlags FieldBindingFlags = BindingFlags.Public
                    | BindingFlags.NonPublic
                    | BindingFlags.Instance | BindingFlags.DeclaredOnly;

        FieldInfo _Field;
        Logical _Sort;

        Sorter<T> _SecordOrder;

        /// <summary>
        /// 初始化。
        /// </summary>
        /// <param name="fieldName">字段名称。</param>
        public Sorter(string fieldName)
            : this(fieldName, Logical.Ascending)
        { }
        /// <summary>
        /// 初始化。
        /// </summary>
        /// <param name="fieldName">字段名称。</param>
        /// <param name="sort">排序方式。</param>
        public Sorter(string fieldName, Logical sort)
        {
            Guard.ArgumentNotNullOrEmptyString(fieldName, "fieldName");
            Guard.EnumValueIsDefined(typeof(Logical), sort, "sort");

            _Field = GetFieldInfo(fieldName);
            _Sort = sort;
        }
        private FieldInfo GetFieldInfo(string fieldName)
        {
            FieldInfo field = typeof(T).GetField(fieldName, FieldBindingFlags);
            if (field == null)
            {
                string message = String.Format("type \"{0}\"'s Field\"{1}\" not find!", typeof(T), fieldName);
                throw new ArgumentException(message);
            }
            return field;
        }

        #region ITypeOrder 成员
        /// <summary>
        /// 能够支持排序的对象类型。
        /// </summary>
        public Type SelectType
        {
            get { return typeof(T); }
        }
        /// <summary>
        /// 字段名称。
        /// </summary>
        public string FieldName
        {
            get { return _Field.Name; }
        }
        /// <summary>
        /// 排序方式。
        /// </summary>
        public Logical Sort
        {
            get { return _Sort; }
        }

        #endregion

        /// <summary>
        /// 转换成字符串。
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            if (this._Sort == Logical.Ascending)
            {
                return String.Format("[{0}]", FieldName);
            }
            return String.Format("[{0}] {1}", FieldName, this._Sort);
        }

        /// <summary>
        /// 第二排序器。
        /// </summary>
        /// <param name="fieldName">字段名称。</param>
        /// <param name="sort">排序方式。</param>
        /// <returns></returns>
        public Sorter<T> Secord(string fieldName, Logical sort)
        {
            Sorter<T> secordOrder = new Sorter<T>(fieldName, sort);
            Sorter<T> order = new Sorter<T>(FieldName, Sort);
            order._SecordOrder = secordOrder;
            return order;
        }
        /// <summary>
        /// 第二排序器。
        /// </summary>
        /// <param name="fieldName">字段名称。</param>
        /// <returns></returns>
        public Sorter<T> Secord(string fieldName)
        {
            return Secord(fieldName, Logical.Ascending);
        }

        /// <summary>
        /// 排序方式。
        /// </summary>
        public enum Logical
        {
            /// <summary>
            /// 升序。
            /// </summary>
            Ascending,
            /// <summary>
            /// 降序。
            /// </summary>
            Descending,
        }
        /// <summary>
        /// 定义类型为比较两个对象而实现的方法。
        /// </summary>
        /// <param name="x">要比较的第一个对象。</param>
        /// <param name="y">要比较的第二个对象。</param>
        /// <returns></returns>
        public int Compare(T x, T y)
        {
            int compare = System.Collections.Comparer.Default.Compare(_Field.GetValue(x), _Field.GetValue(x));
            if (compare != 0)
                return compare;
            return _SecordOrder.Compare(x, y);
        }
    }
}
